#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// ============= 第六课：高级指针应用 =============
// 链表、函数指针、指向指针的指针等高级用法

// 链表节点结构
typedef struct Node {
    int data;
    struct Node *next;
} Node;

// 函数指针类型定义
typedef int (*operation_func)(int, int);
typedef void (*callback_func)(int);

// 函数声明
void demonstrate_linked_list(void);
void demonstrate_function_pointers(void);
void demonstrate_pointer_to_pointer(void);
void demonstrate_void_pointers(void);

// 链表操作函数
Node* create_node(int data);
void insert_at_head(Node **head, int data);
void insert_at_tail(Node **head, int data);
void print_list(Node *head);
void delete_node(Node **head, int data);
void free_list(Node **head);
int list_length(Node *head);

// 数学操作函数
int add(int a, int b);
int subtract(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);

// 回调函数
void print_number(int num);
void print_square(int num);
void print_double(int num);

// 工具函数
void process_array(int *arr, int size, callback_func callback);
void sort_array(int *arr, int size, int (*compare)(int, int));
int ascending_compare(int a, int b);
int descending_compare(int a, int b);

int main(void) {
    printf("=== C语言指针学习 - 第六课：高级指针应用 ===\n\n");
    
    // 1. 链表（动态数据结构）
    demonstrate_linked_list();
    
    // 2. 函数指针
    demonstrate_function_pointers();
    
    // 3. 指向指针的指针
    demonstrate_pointer_to_pointer();
    
    // 4. void指针（通用指针）
    demonstrate_void_pointers();
    
    printf("=== 第六课总结 ===\n");
    printf("1. 链表是动态数据结构，使用指针连接节点\n");
    printf("2. 函数指针可以存储函数地址，实现回调和多态\n");
    printf("3. 指向指针的指针用于修改指针本身\n");
    printf("4. void指针可以指向任何类型的数据\n");
    printf("5. 高级指针技术是C语言的强大特性\n");
    printf("6. 掌握这些技术能编写更灵活的程序\n");
    
    return 0;
}

void demonstrate_linked_list(void) {
    printf("1. 链表（动态数据结构）：\n");
    
    Node *head = NULL;
    
    printf("   创建链表并插入元素:\n");
    
    // 在头部插入
    insert_at_head(&head, 10);
    insert_at_head(&head, 20);
    insert_at_head(&head, 30);
    printf("   头部插入30, 20, 10后: ");
    print_list(head);
    
    // 在尾部插入
    insert_at_tail(&head, 40);
    insert_at_tail(&head, 50);
    printf("   尾部插入40, 50后: ");
    print_list(head);
    
    printf("   链表长度: %d\n", list_length(head));
    
    // 删除节点
    printf("\n   删除节点20:\n");
    delete_node(&head, 20);
    printf("   删除后: ");
    print_list(head);
    
    // 展示链表的内存结构
    printf("\n   链表内存结构:\n");
    Node *current = head;
    int index = 0;
    while (current != NULL) {
        printf("   节点%d: 数据=%d, 地址=%p, next=%p\n", 
               index, current->data, (void*)current, (void*)current->next);
        current = current->next;
        index++;
    }
    
    // 释放链表
    free_list(&head);
    printf("   链表已释放\n\n");
}

void demonstrate_function_pointers(void) {
    printf("2. 函数指针：\n");
    
    // 基本函数指针使用
    printf("   基本函数指针使用:\n");
    operation_func ops[] = {add, subtract, multiply, divide};
    char *op_names[] = {"加法", "减法", "乘法", "除法"};
    
    int a = 20, b = 5;
    printf("   操作数: a = %d, b = %d\n", a, b);
    
    for (int i = 0; i < 4; i++) {
        if (i == 3 && b == 0) {
            printf("   %s: 除数不能为0\n", op_names[i]);
        } else {
            int result = ops[i](a, b);
            printf("   %s: %d\n", op_names[i], result);
        }
    }
    
    // 函数指针作为参数（回调函数）
    printf("\n   函数指针作为参数（回调函数）:\n");
    int numbers[] = {1, 2, 3, 4, 5};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    printf("   原数组: [");
    for (int i = 0; i < size; i++) {
        printf("%d", numbers[i]);
        if (i < size - 1) printf(", ");
    }
    printf("]\n");
    
    printf("   使用不同回调函数处理数组:\n");
    printf("   - 打印原值: ");
    process_array(numbers, size, print_number);
    printf("\n   - 打印平方: ");
    process_array(numbers, size, print_square);
    printf("\n   - 打印双倍: ");
    process_array(numbers, size, print_double);
    printf("\n");
    
    // 函数指针用于排序
    printf("\n   使用函数指针实现不同排序方式:\n");
    int sort_array1[] = {64, 34, 25, 12, 22, 11, 90};
    int sort_array2[] = {64, 34, 25, 12, 22, 11, 90};
    int sort_size = sizeof(sort_array1) / sizeof(sort_array1[0]);
    
    printf("   原数组: [");
    for (int i = 0; i < sort_size; i++) {
        printf("%d", sort_array1[i]);
        if (i < sort_size - 1) printf(", ");
    }
    printf("]\n");
    
    sort_array(sort_array1, sort_size, ascending_compare);
    printf("   升序排序: [");
    for (int i = 0; i < sort_size; i++) {
        printf("%d", sort_array1[i]);
        if (i < sort_size - 1) printf(", ");
    }
    printf("]\n");
    
    sort_array(sort_array2, sort_size, descending_compare);
    printf("   降序排序: [");
    for (int i = 0; i < sort_size; i++) {
        printf("%d", sort_array2[i]);
        if (i < sort_size - 1) printf(", ");
    }
    printf("]\n\n");
}

void demonstrate_pointer_to_pointer(void) {
    printf("3. 指向指针的指针：\n");
    
    // 基本概念
    printf("   基本概念演示:\n");
    int value = 42;
    int *ptr = &value;
    int **ptr_to_ptr = &ptr;
    
    printf("   int value = 42;\n");
    printf("   int *ptr = &value;\n");
    printf("   int **ptr_to_ptr = &ptr;\n\n");
    
    printf("   值和地址关系:\n");
    printf("   value = %d (地址: %p)\n", value, (void*)&value);
    printf("   *ptr = %d (ptr地址: %p)\n", *ptr, (void*)ptr);
    printf("   **ptr_to_ptr = %d (ptr_to_ptr地址: %p)\n", **ptr_to_ptr, (void*)ptr_to_ptr);
    
    // 通过指向指针的指针修改值
    printf("\n   通过指向指针的指针修改值:\n");
    **ptr_to_ptr = 100;
    printf("   执行 **ptr_to_ptr = 100; 后\n");
    printf("   value = %d\n", value);
    
    // 动态分配二维数组
    printf("\n   动态分配二维数组:\n");
    int rows = 3, cols = 4;
    int **matrix = (int**)malloc(rows * sizeof(int*));
    
    for (int i = 0; i < rows; i++) {
        matrix[i] = (int*)malloc(cols * sizeof(int));
    }
    
    // 初始化矩阵
    int counter = 1;
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = counter++;
        }
    }
    
    printf("   3x4动态矩阵:\n");
    for (int i = 0; i < rows; i++) {
        printf("   [");
        for (int j = 0; j < cols; j++) {
            printf("%2d", matrix[i][j]);
            if (j < cols - 1) printf(", ");
        }
        printf("]\n");
    }
    
    // 释放二维数组
    for (int i = 0; i < rows; i++) {
        free(matrix[i]);
    }
    free(matrix);
    printf("   动态矩阵已释放\n\n");
}

void demonstrate_void_pointers(void) {
    printf("4. void指针（通用指针）：\n");
    
    printf("   void指针可以指向任何类型:\n");
    
    // 不同类型的变量
    int int_val = 42;
    float float_val = 3.14f;
    char char_val = 'A';
    char str_val[] = "Hello";
    
    // void指针数组
    void *void_ptrs[] = {&int_val, &float_val, &char_val, str_val};
    char *type_names[] = {"整数", "浮点数", "字符", "字符串"};
    
    printf("   使用void指针存储不同类型的地址:\n");
    for (int i = 0; i < 4; i++) {
        printf("   void_ptrs[%d] 指向 %s (地址: %p)\n", 
               i, type_names[i], void_ptrs[i]);
    }
    
    // 使用void指针访问数据（需要类型转换）
    printf("\n   通过void指针访问数据（需要类型转换）:\n");
    printf("   *(int*)void_ptrs[0] = %d\n", *(int*)void_ptrs[0]);
    printf("   *(float*)void_ptrs[1] = %.2f\n", *(float*)void_ptrs[1]);
    printf("   *(char*)void_ptrs[2] = %c\n", *(char*)void_ptrs[2]);
    printf("   (char*)void_ptrs[3] = %s\n", (char*)void_ptrs[3]);
    
    // 通用复制函数示例
    printf("\n   通用内存复制函数示例:\n");
    int source[] = {1, 2, 3, 4, 5};
    int dest[5];
    
    // 使用void指针实现通用复制
    void *src_ptr = source;
    void *dest_ptr = dest;
    size_t size = sizeof(source);
    
    // 模拟memcpy
    char *src_bytes = (char*)src_ptr;
    char *dest_bytes = (char*)dest_ptr;
    for (size_t i = 0; i < size; i++) {
        dest_bytes[i] = src_bytes[i];
    }
    
    printf("   源数组: [");
    for (int i = 0; i < 5; i++) {
        printf("%d", source[i]);
        if (i < 4) printf(", ");
    }
    printf("]\n");
    
    printf("   目标数组: [");
    for (int i = 0; i < 5; i++) {
        printf("%d", dest[i]);
        if (i < 4) printf(", ");
    }
    printf("]\n");
    
    printf("   复制成功！\n\n");
}

// 链表操作函数实现
Node* create_node(int data) {
    Node *new_node = (Node*)malloc(sizeof(Node));
    if (new_node != NULL) {
        new_node->data = data;
        new_node->next = NULL;
    }
    return new_node;
}

void insert_at_head(Node **head, int data) {
    Node *new_node = create_node(data);
    if (new_node != NULL) {
        new_node->next = *head;
        *head = new_node;
    }
}

void insert_at_tail(Node **head, int data) {
    Node *new_node = create_node(data);
    if (new_node == NULL) return;
    
    if (*head == NULL) {
        *head = new_node;
        return;
    }
    
    Node *current = *head;
    while (current->next != NULL) {
        current = current->next;
    }
    current->next = new_node;
}

void print_list(Node *head) {
    printf("[");
    Node *current = head;
    while (current != NULL) {
        printf("%d", current->data);
        if (current->next != NULL) printf(" -> ");
        current = current->next;
    }
    printf("]\n");
}

void delete_node(Node **head, int data) {
    if (*head == NULL) return;
    
    if ((*head)->data == data) {
        Node *temp = *head;
        *head = (*head)->next;
        free(temp);
        return;
    }
    
    Node *current = *head;
    while (current->next != NULL && current->next->data != data) {
        current = current->next;
    }
    
    if (current->next != NULL) {
        Node *temp = current->next;
        current->next = current->next->next;
        free(temp);
    }
}

void free_list(Node **head) {
    Node *current = *head;
    while (current != NULL) {
        Node *temp = current;
        current = current->next;
        free(temp);
    }
    *head = NULL;
}

int list_length(Node *head) {
    int length = 0;
    Node *current = head;
    while (current != NULL) {
        length++;
        current = current->next;
    }
    return length;
}

// 数学操作函数实现
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return b != 0 ? a / b : 0; }

// 回调函数实现
void print_number(int num) { printf("%d ", num); }
void print_square(int num) { printf("%d ", num * num); }
void print_double(int num) { printf("%d ", num * 2); }

// 工具函数实现
void process_array(int *arr, int size, callback_func callback) {
    for (int i = 0; i < size; i++) {
        callback(arr[i]);
    }
}

void sort_array(int *arr, int size, int (*compare)(int, int)) {
    // 简单的冒泡排序
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (compare(arr[j], arr[j + 1]) > 0) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int ascending_compare(int a, int b) {
    return a - b;
}

int descending_compare(int a, int b) {
    return b - a;
} 